/***************************************************************************************

***************************************************************************************/



/*
*************************************************************************************
* File name: global.h
* Function:  global definitions for for IVC decoder.
*
*************************************************************************************
*/

#ifndef _GLOBAL_H_
#define _GLOBAL_H_

#include <stdio.h>                              //!< for FILE
#include "defines.h"
#include "common.h"

//! Boolean Type
typedef enum {
  FALSE,
  TRUE
} Boolean;

// global picture format dependend buffers, mem allocation in decod.c ******************
int  **refFrArr;                                //!< Array for reference frames of each block


uchar_t *reference_frame[32][3];
uchar_t *p_ref_frm[32][3]; // only a pointer

uchar_t **b_ref_frm, **f_ref_frm;

uchar_t *p_mref[32];
uchar_t *p_mcef[32][2];

uchar_t *p_cur_frm[3];
uchar_t *imgY_rec;
uchar_t *imgU_rec;
uchar_t *imgV_rec;

uchar_t *img_prev; // only will be used in calculating PSNR

// B pictures
int  Bframe_ctr;
int prevP_tr, nextP_tr, P_interval;
int  frame_no;

int  **refFrArr_frm;

int nextP_tr_frm;

#define  snprintf _snprintf
#define ET_SIZE 300      //!< size of error text buffer
char errortext[ET_SIZE]; //!< buffer for error message for exit with error()

//added at ITM version
int  CSyntax;            
int  StartCodeValue;     

int  Min_V_MV;           
int  Max_V_MV;
int  Min_H_MV;
int  Max_H_MV;
//added at ITM version

//! definition of IVC syntax elements
typedef enum {
  SE_HEADER,
  SE_MBTYPE,
  SE_MVD,
  SE_CBP_INTRA,
  SE_LUM_DC_INTRA,
  SE_CHR_DC_INTRA,
  SE_LUM_AC_INTRA,
  SE_CHR_AC_INTRA,
  SE_CBP_INTER,
  SE_LUM_DC_INTER,
  SE_CHR_DC_INTER,
  SE_LUM_AC_INTER,
  SE_CHR_AC_INTER,
  SE_DELTA_QUANT_INTER,
  SE_DELTA_QUANT_INTRA,
  SE_BFRAME,
  SE_EOS,
  SE_MAX_ELEMENTS //!< number of maximum syntax elements, this MUST be the last one!
} SE_type;        // substituting the definitions in element.h


typedef enum {
  BITS_TOTAL_MB,
  BITS_HEADER_MB,
  BITS_INTER_MB,
  BITS_CBP_MB,
  BITS_COEFF_Y_MB,
  BITS_COEFF_UV_MB,
  MAX_BITCOUNTER_MB
} BitCountType;

typedef enum {
  P_IMG = 0,
  B_IMG,
  I_IMG,
} PictureType;

typedef struct
{
  unsigned int    Dbuffer;
  int             Dbits_to_go;
  uchar            *Dcodestrm;
  int             *Dcodestrm_len;
} DecodingEnvironment;

typedef DecodingEnvironment *DecodingEnvironmentPtr;

//! struct for context management
typedef struct
{
  unsigned char	MPS;   
  unsigned int	LG_PMPS; 	
  unsigned char	cycno;
} BiContextType;

typedef BiContextType *BiContextTypePtr;
/**********************************************************************
* C O N T E X T S   F O R   R M   S Y N T A X   E L E M E N T S
**********************************************************************
*/

#define NUM_MB_TYPE_CTX  11
#define NUM_B8_TYPE_CTX  9
#define NUM_MV_RES_CTX   10
#define NUM_DELTA_QP_CTX 4


typedef struct
{
  BiContextType mb_type_contexts [4][NUM_MB_TYPE_CTX];
  BiContextType b8_type_contexts [2][NUM_B8_TYPE_CTX];
  BiContextType mv_res_contexts  [2][NUM_MV_RES_CTX];
  BiContextType delta_qp_contexts[NUM_DELTA_QP_CTX];
} MotionInfoContexts;

#define NUM_CBP_CTX    4
#define NUM_MAP_CTX   16
#define NUM_LAST_CTX  16

#define NUM_ONE_CTX    5
#define NUM_ABS_CTX    5

#define NUM_IPR_CTX    4
#define NUM_CIPR_CTX   4

typedef struct
{
    BiContextType qsplit_contexts[1];
	BiContextType  ipr_contexts [NUM_IPR_CTX];
	BiContextType  cipr_contexts[NUM_CIPR_CTX];
  BiContextType  cbp_contexts [3][NUM_CBP_CTX];
  BiContextType  one_contexts [NUM_BLOCK_TYPES][NUM_ONE_CTX];
  BiContextType  abs_contexts [NUM_BLOCK_TYPES][NUM_ABS_CTX];
  BiContextType  map_contexts [NUM_BLOCK_TYPES][NUM_MAP_CTX];
  BiContextType  last_contexts[NUM_BLOCK_TYPES][NUM_LAST_CTX];
  BiContextType  tu_size_context[1];
} TextureInfoContexts;
struct img_par;
struct stat_par;

// struct of bbv buffer, yin hai cang
typedef struct BbvBuffer_t
{
  char  bbv_mode;           // 0:not 0xFFFF, 1:0xFFFF
  char  vec_flag;           // the flag of video edit code(vec), 0: vec doesn't exit, 1: vec exit.
  int   bitrate;            // bit per second (bit/s)
  float framerate;          // frame per second (frame/s)
  float bbv_delay;          //(s)
  float low_delay;          // 
  int   BBS_size;           // 
  float frmout_interval;    // 
  int   currFrm_max_bit;    // 
  int   currFrm_min_bit;    // 
  int   frm_no;             // 
  int   check_continue;     // 
  int   frame_code_bits;    //
  int   *FrameBits;         // 
} BbvBuffer_t;

//ITM_r2
int  pminBBSsize;
int  pminFsize;
int  pbbv_mode;
int  pbitrate;
//ITM_r2

//ITM_r2
typedef struct StatBits {
  int   curr_frame_bits;
  int   prev_frame_bits;
  int   emulate_bits;
  int   prev_emulate_bits;
  int   last_unit_bits;
  int   bitrate;
  int   total_bitrate[1000];
  int   coded_pic_num;
  int   time_s;
} StatBits;

typedef struct syntaxelement
{
  int           type;                  //!< type of syntax element for data part.
  int           value1;                //!< numerical value of syntax element
  int           value2;                //!< for blocked symbols, e.g. run/level
  int           len;                   //!< length of code
  int           inf;                   //!< info part of UVLC code
  unsigned int  bitpattern;            //!< UVLC bitpattern
  int           context;               //!< AEC context
  int           k;                     //!< AEC context for coeff_count,uv
  int           golomb_grad;		   //!< Needed if type is a golomb element
  int           golomb_maxlevels;	   //!< If this is zero, do not use the golomb coding
#if TRACE
#define       TRACESTRING_SIZE 100           //!< size of trace string
  char          tracestring[TRACESTRING_SIZE]; //!< trace string
#endif

  //! for mapping of UVLC to syntaxElement
  void    (*mapping)(int len, int info, int *value1);
  //! used for AEC: refers to actual coding method of each individual syntax element type
  void  (*reading)(struct syntaxelement *, struct img_par *, DecodingEnvironmentPtr);

} SyntaxElement;


#if TRACE
void  trace2out(SyntaxElement *se);
#endif

//! Macroblock
typedef struct macroblock
{
  int           qp;
  int           slice_nr;
  int           delta_quant;          //!< for rate control
  struct macroblock   *mb_available[3][3]; /*!< pointer to neighboring MBs in a 3x3 window of current MB, which is located at [1][1]
                                           NULL pointer identifies neighboring MBs which are unavailable */

  // some storage of macroblock syntax elements for global access
  int           mb_type;
  int           trans_type;
  int           mvd[2][BLOCK_MULTIPLE][BLOCK_MULTIPLE][2];      //!< indices correspond to [forw,backw][block_y][block_x][x,y]
  int           cbp, cbp_blk;
  unsigned long cbp_bits;

  int           b8mode[4];
  int           b8pdir[4];
  int           splite_flag[4];
  int           fw_ref[4];

  int           c_ipred_mode;         //!< chroma intra prediction mode

  int           lf_disable;

  int			skip_flag;

  struct macroblock   *mb_available_up;   //!< pointer to neighboring MB (AEC)
  struct macroblock   *mb_available_left; //!< pointer to neighboring MB (AEC)
  int           mbAddrA, mbAddrB, mbAddrC, mbAddrD;
  int           mbAvailA, mbAvailB, mbAvailC, mbAvailD;

} Macroblock;

//! Bitstream
typedef struct
{
  // AEC Decoding
  int           read_len;           //!< actual position in the codebuffer, AEC only
  int           code_len;           //!< overall codebuffer length, AEC only
  // UVLC Decoding
  int           frame_bitoffset;    //!< actual position in the codebuffer, bit-oriented, UVLC only
  int           bitstream_length;   //!< over codebuffer lnegth, byte oriented, UVLC only
  // ErrorConcealment
  uchar          *streamBuffer;      //!< actual codebuffer for read bytes
} Bitstream;

//! struct to characterize the state of the arithmetic coding engine
typedef struct datapartition
{

  Bitstream           *bitstream;
  DecodingEnvironment de_AEC;

  int     (*readSyntaxElement)(SyntaxElement *, struct img_par *, struct datapartition *);
  /*!< virtual function;
  actual method depends on chosen   entropy coding method  */
} DataPartition;

//! Slice
typedef struct
{
  int                 picture_id;
  int                 qp;
  int                 picture_type; //!< picture type
  int                 start_mb_nr;
  int                 max_part_nr;  //!< number of different partitions
  int                 num_mb;       //!< number of MBs in the slice

  DataPartition       *partArr;     //!< array of partitions
  MotionInfoContexts  *mot_ctx;     //!< pointer to struct of context models for use in AEC
  TextureInfoContexts *tex_ctx;     //!< pointer to struct of context models for use in AEC
} Slice;

typedef struct pix_pos
{
  int available;   //ABCD
  int mb_addr;    //MB position
  int x;         
  int y;
  int pos_x;     //4x4 x-pos
  int pos_y;    
} PixelPos;

typedef enum {
  UVLC,
  AEC
} SymbolMode;


// image parameters
typedef struct img_par
{
  int number;                                 //<! frame number
  int current_mb_nr;						  // bitstream order
  int max_mb_nr;
  int current_slice_nr;
  int **intra_block;
  int tr;                                     //<! temporal reference, 8 bit, wrapps at 255
  int qp;                                     //<! quant for the current frame
  int type;                                   //<! image type INTER/INTRA
  int typeb;
  int width;
  int height;
  int width_cr;                               //<! width chroma
  int height_cr;                              //<! height chroma
  int iStride;
  int iStrideC;
  int mb_y;
  int mb_x;
  int block_y;
  int pix_y;
  int pix_x;
  int pix_c_y;
  int block_x;
  int pix_c_x;

  int ***mv;                                 
  pel_t predblk[256];                            //<! predicted block, 16x16
  int ***bimv;
  int m7[16][16];                             //<! final 4x4 block. Extended to 16x16 for ABT
  int m8[/*2*/4][8][8];                       //<! final 4x4 block. Extended to 16x16 for IVC
  int **ipredmode;                            //<! prediction type
  int tab_sqr[256];
  int cod_counter;                            //<! Current count of number of skipped macroblocks in a row

  int ***dfMV;                             
  int ***dbMV;                            
  int **fw_refFrArr;                         
  int **bw_refFrArr;                      

  int ***mv_frm;
  int **fw_refFrArr_frm;                    
  int **bw_refFrArr_frm;                  
  int imgtr_next_P;
  int imgtr_last_P;
  int tr_frm;
  int imgtr_last_prev_P;

  int no_forward_reference;			
  int seq_header_indicate;			
  int B_discard_flag;						

  int max_ref_num;

  // B pictures
  int ***fw_mv;                              
  int ***bw_mv;                     
  int subblock_x;
  int subblock_y;

  int buf_cycle;

  int direct_type;

  int framepoc;							      //<! poc of this frame 

  unsigned int pic_distance;

  signed int PicDistanceMsb;
  unsigned int PrevPicDistanceLsb;
  signed int CurrPicDistanceMsb;
  unsigned int ThisPOC;

  int PicWidthInMbs;
  int PicHeightInMbs;
  int PicSizeInMbs;
  int types;

  int Bframe_number;
  int auto_crop_right;                        //<! Bug Fix: correct picture size for outputted reconstructed pictures
  int auto_crop_bottom;

  //!EDIT START <added by  AEC
  Slice       *currentSlice;                  //<! pointer to current Slice data struct
  int		  is_v_block;
  int		  is_intra_block;
  int new_seq_header_flag;  
  int new_sequence_flag;    
  int last_pic_bbv_delay;                     //<! last picture's bbv_delay
  int sequence_end_flag;					  //<! ITM_r2

  int current_slice_header_flag;
  int p_subtype;

} img_params;
Macroblock          *mb_data;

extern img_params *img;
extern Bitstream *currStream;

// signal to noice ratio parameters
typedef struct
{
  float snr_y;                                //<! current Y SNR
  float snr_u;                                //<! current U SNR
  float snr_v;                                //<! current V SNR
  float snr_sum_y;                               //<! Average SNR Y(dB) remaining frames
  float snr_sum_u;                               //<! Average SNR U(dB) remaining frames
  float snr_sum_v;                               //<! Average SNR V(dB) remaining frames
}snr_par;

int tot_time;

// input parameters from configuration file
typedef struct
{
  char infile[1000];						  //<! IVC input
  char outfile[1000];						  //<! Decoded YUV 4:2:0 output
  char reffile[1000];						  //<! Optional YUV 4:2:0 reference file for SNR measurement
  int FileFormat;							  //<! File format of the Input file, PAR_OF_ANNEXB or PAR_OF_RTP
  int buf_cycle;							  //<! Frame buffer size
  int yuv_structure;						  //<! Specifies reference frame's yuv structure
  int check_BBV_flag;						  //<! Check BBV buffer (0: disable, 1: enable)
  int output_syntaxcheck;                     //<! Output the result of syntax checking
  int ref_pic_order;                 // ref order
  int output_dec_pic;                // output_dec_pic
}inp_params;

extern inp_params *input;

// files
FILE *p_out;								  //<! pointer to output YUV file
FILE *p_ref;								  //<! pointer to input original reference YUV file file

FILE *p_log;								  //<! SNR file

#if TRACE
FILE *p_trace;
#endif

FILE *p_sreport;   

void read_ipred_block_modes(img_params *img,int b8, int b4);

void set_MB_parameters (img_params *img, int mb);
int scale_motion_vector(int motion_vector, int currblkref, int neighbourblkref, int ref);
// prototypes
void init_conf(inp_params *inp,int numpar,char **config_str);
void report(inp_params *inp, img_params *img, snr_par *snr);
void find_snr(snr_par *snr,img_params *img, FILE *p_ref, uchar_t *img_prev);

int  decode_one_frame(img_params *img,inp_params *inp, snr_par *snr);
void init_frame(img_params *img, inp_params *inp);
void init_frame_buffer();

void write_frame(img_params *img, FILE *p_out);
void write_prev_Pframe(img_params *img,FILE *p_out, uchar_t *pDst);// B pictures
void copy_Pframe(img_params *img, uchar_t *pDst);// B pictures


int  read_new_slice();
void decode_one_slice(img_params *img,inp_params *inp);
void picture_data(img_params *img);
void start_macroblock(img_params *img);
void init_macroblock_Bframe(img_params *img);// B pictures
int  read_one_macroblock(img_params *img);
int  decode_one_macroblock(img_params *img);

int  sign(int a , int b);

int Header();

void DeblockFrame(img_params *img, uchar_t *pic_y, uchar_t *pic_u, uchar_t *pic_v);

// Direct interpolation
void CheckAvailabilityOfNeighbors(img_params *img);

void error(char *text, int code);

// dynamic mem allocation
int  init_global_buffers(inp_params *inp, img_params *img);
void free_global_buffers(img_params *img);

void Update_Picture_Buffers();
void frame_postprocessing(img_params *img);

void report_frame(snr_par *snr,int tmp_time);

#define PAYLOAD_TYPE_IDERP 8

Bitstream *AllocBitstream();
void FreeBitstream();
void tracebits2(const char *trace_str, int len, int info);

int get_direct_mv (int****** mv,int mb_x,int mb_y);
void free_direct_mv (int***** mv,int mb_x,int mb_y);

int	*****direct_mv; // only to verify result  
//int	  direct_mv[45][80][4][4][3];	// only to verify result  
int ipdirect_x,ipdirect_y;
int demulate_enable;	
int check_picture_end;
char spos0[30];         //syntax position, used for marker_bit checking, ITM_r2
char spos1[30];         //syntax position, used for marker_bit checking, ITM_r2
int aspect_ratio_information;
int frame_rate_code; 
int bit_rate_value; 
int bbv_buffer_size;
int slice_row_nr;
int currentbitoffset;
int currentBytePosition;
int chroma_format;
int profile_id;
int level_id;
int progressive_sequence;
int horizontal_size;
int vertical_size;
int chroma_format;
int sample_precision;
int aspect_ratio_information;
int frame_rate_code;
int bit_rate;
int low_delay;
int bit_rate_lower;
int bit_rate_upper;
int video_format;
int video_range;  
int color_description;
int color_primaries;
int transfer_characteristics;
int matrix_coefficients;
int display_horizontal_size;
int display_vertical_size;


int FrameNum;	
int eos;
int pre_img_type;
int pre_img_types;
//int pre_str_vec;
int pre_img_tr;
int pre_img_qp;
int pre_tmp_time;   
int RefPicExist;	 
int dec_ref_num;                //ref order
snr_par *snr;

/* video edit code */
int vec_flag;

/* Copyright_extension() header */
int copyright_flag;
int copyright_identifier;
int original_or_copy;
long long copyright_number_1;
int copyright_number_2;
int copyright_number_3;
/* Camera_parameters_extension */
int camera_id;
int height_of_image_device;
int focal_length;
int f_number;
int vertical_angle_of_view;
int camera_position_x_upper;
int camera_position_x_lower;
int camera_position_y_upper;
int camera_position_y_lower;
int camera_position_z_upper;
int camera_position_z_lower;
int camera_direction_x;
int camera_direction_y;
int camera_direction_z;
int image_plane_vertical_x;
int image_plane_vertical_y;
int image_plane_vertical_z;

/* I_pictures_header() */ 
int stream_length_flag;
int stream_length;
int picture_distance;
int picture_decode_order_flag;
int picture_decode_order;
int progressive_frame;
int abt_enable;
int if_type;
int fixed_picture_qp;
int picture_qp;
int time_code_flag;
int time_code;

int loop_filter_disable;
int Alpha,Beta;

int bby_delay;
int hour;
int minute;
int sec;
int frame_offset;
int bbv_check_times;

/* Pb_picture_header() */
int picture_coding_type;
int bbv_delay;
int bbv_delay_extension;  
int  marker_bit;

/* slice_header() */
int start_code_prefix;
int slice_vertical_position;  
int slice_vertical_position_extension;
int slice_start_code;
int fixed_picture_qp;
int fixed_slice_qp;
int slice_qp;
int StartCodePosition;



#define I_PICTURE_START_CODE    0xB3
#define PB_PICTURE_START_CODE   0xB6
#define SLICE_START_CODE_MIN    0x00
#define SLICE_START_CODE_MAX    0xAF
#define USER_DATA_START_CODE    0xB2
#define SEQUENCE_HEADER_CODE    0xB0
#define SEQUENCE_END_CODE       0xB1
#define VIDEO_EDIT_CODE         0xB7


#define SEQUENCE_DISPLAY_EXTENSION_ID            2
#define COPYRIGHT_EXTENSION_ID                   4
#define CAMERAPARAMETERS_EXTENSION_ID            11
#define PICTURE_DISPLAY_EXTENSION_ID             7

typedef struct{
  int reserved;
  int camera_id;
  int height_of_image_device;
  int focal_length;
  int f_number;
  int vertical_angle_of_view;
  int camera_position_x;
  int camera_position_y;
  int camera_position_z;
  int camera_direction_x;
  int camera_direction_y;
  int camera_direction_z;
  int image_plane_vertical_x;
  int image_plane_vertical_y;
  int image_plane_vertical_z;
} CameraParamters;

extern CameraParamters *camera;

void malloc_slice(inp_params *inp, img_params *img);
DataPartition *AllocPartition();
void FreePartition (DataPartition *dp);
void getNeighbour(int curr_mb_nr, int xN, int yN, int luma, PixelPos *pix);
void getLuma8x8Neighbour (int curr_mb_nr, int b8_x, int b8_y, int rel_x, int rel_y, PixelPos *pix);
void get_mb_pos (int mb_addr, int *x, int*y);
int  AEC_startcode_follows(img_params *img, int eos_bit);
void free_slice(img_params *img);  

int b_pre_dec_intra_img;
int pre_dec_img_type;
int slice_horizontal_positon;    
int slice_horizontal_positon_extension;
#endif

